/**
 *
 * © Bahadir Zeren 2011
 * bzeren@gmail.com
 * No warranties, express or implied, are made for this program.
 *
 */

package org.baatar.opt.genetic.impl.prmopt;

import java.util.Comparator;
import org.baatar.opt.genetic.chromosome.IChromosome;
import org.baatar.opt.genetic.mutation.IMutator;
import org.baatar.util.RandomUtil;

/**
 *
 * Mutation class for Boolean structured chromosomes.
 * 
 */
public class Mutator implements IMutator<Boolean> {
    @Override
    public void mutate(IChromosome<Boolean> chromosome, double mutationRatio) {
        for (int i = 0; i < chromosome.getChromosomeLength(); i++) {
            if (RandomUtil.getRandDouble() < mutationRatio) {
                if (chromosome.getGeneValue(i))
                    chromosome.setGeneValue(i, false);
                else
                    chromosome.setGeneValue(i, true);
            }
        }
    }

    @Override
    public void mutateGreedy(IChromosome<Boolean> chromosome,
                                double greedRatio,
                                Comparator<IChromosome<Boolean>> comparator) {
        if (RandomUtil.getRandDouble() < greedRatio) {
            int pos1 = RandomUtil.getRandNumber(chromosome.getChromosomeLength());
            int pos2 = RandomUtil.getRandNumber(chromosome.getChromosomeLength() - pos1) + pos1;
            for (int i = pos1; i <= pos2; i++) {

                try {
                    IChromosome<Boolean> savedChromosome  = (IChromosome<Boolean>) chromosome.clone();

                    if (chromosome.getGeneValue(i))
                        chromosome.setGeneValue(i, false);
                    else
                        chromosome.setGeneValue(i, true);
                    chromosome.calculateFitness();

                    if (comparator.compare(chromosome, savedChromosome) < 0) {
                        if (chromosome.getGeneValue(i))
                            chromosome.setGeneValue(i, false);
                        else
                            chromosome.setGeneValue(i, true);
                        chromosome.calculateFitness();
                    }
                } catch(Exception ex) {
                }
            }
        }
    }
}
